using System;
using System.Collections.Generic;

#if NET_COMPATABLE
using System.Diagnostics;
#endif 

namespace cash
{
	/// <summary>
	/// The Executive launches system commands.
	/// </summary>
	public static class Executive
	{
		/// <summary>
		/// This function executes an external tool, pausing the shell
		/// while it does so.
		/// </summary>
		/// <param name="tool"> The name of the tool to run e.g. uname <see cref="System.String"/></param>
		/// <param name="args"> The paramaters to pass to the tool e.g. -n <see cref="System.String"/>  </param>
		/// <returns>string The standard output generated by the tool. (The final line-break, if any, is filtered)</returns>
		public static string ReturnBlockingTool(string tool, string args)
		{
#if DEBUG
			Console.WriteLine("DEBUG: Running external tool \"{0}\" with args \"{1}\"",tool,args);
#endif 
			
#if !NET_COMPATABLE
			Console.WriteLine("ERROR: Executing external processes is not supported on this system.");
			Console.WriteLine("For more information refer to the cash documentation.");
			throw new Exception("Execution of external processes is not supported due to OS constraints.",
			                    new Exception("If your operating system IS capable of external processes, set your conditional compilation flags to NET_COMPATABLE"));
#endif 
			
			try 
			{
				ProcessStartInfo ExternalInformation = new ProcessStartInfo(tool, args);
				ExternalInformation.UseShellExecute = false;
				ExternalInformation.RedirectStandardOutput = true;
				
				
				Process ExternalTool = Process.Start(ExternalInformation);
				ExternalTool.WaitForExit();
				string Result = ExternalTool.StandardOutput.ReadToEnd().TrimEnd('\n');
#if DEBUG
				Console.WriteLine("DEBUG: Tool returned \"{0}\" and exit code {1}.",Result,ExternalTool.ExitCode);
#endif 
				return Result;
			}
			catch(Exception e)
			{
				Console.WriteLine("There was a problem with executing the external command \"{0}\"",tool);
				Console.WriteLine("Check with your system administrator that this command is installed.");
				Console.WriteLine("Problems with external commands could impact the shell's stability. Would you like to continue using it? (Y/N)");
				bool CommandOK = false;
				while(!CommandOK)
				{
					string Response = Console.ReadLine();
					if (Response.ToUpper() == "N")
					{
						MainClass.Exit();
					}
					else if(Response.ToUpper() == "Y")
					{
						CommandOK = true;
						Console.WriteLine("OK, continuing as normal...");
					}
					else 
					{
						Console.WriteLine("ERROR: Cannot parse this response into a boolean one. Use only the Y or N keys.");
					}
				}
				return "CMDERR";
			}
		}
		
		public static void ExecuteCommandList(List<Command> Commands)
		{
			#if DEBUG
			Console.WriteLine("DEBUG: Executing command queue with {0} item(s)",Commands.Count);
#endif 
			for(int i=0; i<Commands.Count; i++)
			{
				#if DEBUG
				Console.WriteLine("DEBUG: Executing {0}th command queue with {1} item(s)",i+1,Commands.Count);
				#endif 
				if(Commands[i].CommandType == CommandTypes.SimpleCommand)
				{
					Commands[i].Execute();
					Console.Write(Commands[i].StdOut);
				}
			}
		}
		
	}
}
